<?php
declare(strict_types = 1);

namespace app\logic;

use app\ArrayToolkit;
use think\Exception;
use think\facade\Db;

class User extends BaseLogic
{
    public function createUser(array $fields)
    {
        $fields = $this->filterUserFields($fields);

        if (empty($fields)) {
            return null;
        }

        if (!ArrayToolkit::requireds($fields, ['username', 'password', 'login_ip'])) {
            $this->throwHttpException(500, '缺少必要参数');
        }

        if (!empty($this->getUserByUsername($fields['username']))) {
            $this->throwHttpException(500, '该用户名已存在');
        }

        $fields['password'] = md5($fields['password']);

        $this->getUserModel()->save($fields);

        return $this->getUserByUsername($fields['username']);
    }

    public function syncUser()
    {
        $command = "php ".__DIR__."/../../think sync:syncData";
        exec($command, $output, $return);
        return true;
    }

    public function updateUser($id, $fields)
    {
        $user = $this->getUserById($id);

        if (empty($user)) {
            $this->throwHttpException(500, '该用户不存在');
        }

        $fields = $this->filterUserFields($fields);

        if (empty($fields)) {
            return null;
        }

        if ($user['username'] != $fields['username'] && !empty($this->getUserByUsername($fields['username']))) {
            $this->throwHttpException(500, '该用户名已存在');
        }

        if (!empty($fields['password'])) {
            unset($fields['password']);
        }

        $this->getUserModel()->where('id', $user['id'])->update($fields);

        return $this->getUserById($id);
    }

    public function changePassword($id, $password)
    {
        $user = $this->getUserById($id);

        if (empty($user)) {
            $this->throwHttpException(500, '该用户不存在');
        }

        $this->getUserModel()->where('id', $id)->update(['password' => md5($password)]);
    }

    public function deleteUser($id)
    {
        $user = $this->getUserById($id);

        if (empty($user)) {
            $this->throwHttpException(500, '该用户不存在');
        }
        return $this->getUserModel()->where('id', $id)->delete();
    }

    public function batchCreateUsers($users)
    {
        if (empty($users)) {
            return false;
        }

        foreach ($users as &$user) {
            $user = $this->filterUserFields($user);
        }

        Db::startTrans();
        try {
            $this->getUserModel()->saveAll($users);
            Db::commit();
        } catch (\Exception $e) {
            Db::rollback();
        }

        return true;
    }

    public function batchUpdateUser($users)
    {
        if (empty($users)) {
            return false;
        }

        foreach ($users as &$user) {
            $id = $user['id'];
            $user = $this->filterUserFields($user);
            $user['id'] = $id;
        }

        Db::startTrans();
        try {
            $this->getUserModel()->saveAll($users);
            Db::commit();
        } catch (\Exception $e) {
            Db::rollback();
        }

        return true;
    }

    public function getUserById($id)
    {
        if (empty($id)) {
            return [];
        }
        return $this->getUserModel()->getUserById($id);
    }

    public function getUserByOpenId($openId): array
    {
        if (empty($openId)) {
            return [];
        }

        return $this->getUserModel()->getByOpenId($openId);
    }

    public function findUserByIds(array $ids)
    {
        if (empty($ids)) {
            return [];
        }
        return $this->getUserModel()->findByIds($ids);
    }

    public function login($username, $password, $ip)
    {
        $user = $this->getUserByUsername($username);

        if (empty($user)) {
            $this->throwHttpException(500, '该用户名不存在');
        }

        if (md5($password) != $user['password']) {
            $this->throwHttpException(500, '密码错误');
        }

        $this->getUserModel()::update(['login_ip' => $ip], ['id' => $user['id']]);
        unset($user['password']);
        return $user;
    }

    public function getUserByUsername($username)
    {
        if (empty($username)) {
            return [];
        }
        return $this->getUserModel()->getByUsername($username);
    }

    public function findAllWeChatUser()
    {
        return $this->getUserModel()->findAllWeChatUser();
    }

    public function getByFields($field, $value)
    {
        return $this->getUserModel()->getByFields($field, $value);
    }

    public function countUser(array $conditions)
    {
        return $this->getUserModel()->countUser($conditions);
    }

    public function searchUsers(array $conditions, array $orderBy, $start, $limit, $isShowOpenId = false)
    {
        $users = $this->getUserModel()->searchUsers($conditions, $orderBy, $start, $limit);

        return $this->buildUsers($users, $isShowOpenId);
    }


    protected function buildUsers($users, $isShowOpenId)
    {
        if (empty($users)) {
            return $users;
        }

        $fields = [
            'id',
            'username',
            'nickname',
            'avatar',
            'login_ip',
            'created_time'
        ];

        if ($isShowOpenId) {
            $fields[] = 'wechat_open_id';
        }

        foreach ($users as &$user) {
            $user = ArrayToolkit::parts($user, $fields);
        }

        return $users;
    }

    protected function filterUserFields(array $fields)
    {
        return ArrayToolkit::parts($fields, [
            'username',
            'nickname',
            'avatar',
            'password',
            'login_ip',
            'created_time',
            'wechat_open_id',
            'is_delete'
        ]);
    }

    /**
     * @return \app\model\User
     */
    protected function getUserModel()
    {
        return $this->getModel('User');
    }
}
